﻿using System;
using System.Collections.Generic;
using System.Linq;
using SlamCms.Common;

namespace SlamCms.Data
{
    internal class TagTreeCountsQueryResult
    {
        private readonly QueryParameters _parameters;
        private readonly IDictionary<int, int> _results;

        internal TagTreeCountsQueryResult(QueryParameters parameters, IDictionary<int, int> results)
        {
            _parameters = parameters;
            _results = results;
        }

        public QueryParameters Parameters
        {
            get
            {
                return _parameters;
            }
        }

        public IDictionary<int, int> Results
        {
            get
            {
                return _results;
            }
        }

        internal static TagTreeCountsQueryResult Get(DataContext dataContext, QueryParameters queryParameters, string tagTreeId, bool topLevelOnly)
        {
            var parameters = (QueryParameters)queryParameters.Clone();

            // ensure to remove parameters not needed for this query so they
            // don't affect the cache hash code
            parameters.IncludeTags = false;
            parameters.Take = 0;
            parameters.Name = null;
            parameters.CountOnly = false;
            parameters.OrderBy = null;
            parameters.OrderByFeatureOnLocationLevel = null;
            parameters.OrderByFeatureOnTagLevel = null;

            parameters.Parameters.Add("tagTreeId", tagTreeId);
            parameters.Parameters.Add("topLevelOnly", topLevelOnly);

            var queryCacheKey = "{0}_{1}".F(Constants.Cache.TagTreeCounts, parameters.GetHashCode());
            if (parameters.Cache.Behavior != QueryCacheBehavior.NoCache && dataContext.Cache.Contains(queryCacheKey, false))
                return dataContext.Cache.Get<TagTreeCountsQueryResult>(queryCacheKey);

            var sqlGenerator = new TagTreeCountsSqlQueryGenerator(parameters);
            var sql = sqlGenerator.Generate();

            var results = dataContext.Database.Query<TagHierarchyPositionCount>(sql).ToDictionary(x => x.PositionId, x => x.ContentItemCount);

            var tagTreeCountsQueryResult = new TagTreeCountsQueryResult(parameters, results);
            dataContext.Cache.Save(queryCacheKey, tagTreeCountsQueryResult, TimeSpan.FromMinutes(parameters.Cache.Duration), true);
            return tagTreeCountsQueryResult;
        }
    }
}
